#include <stdio.h>
#include <stdlib.h>

#include "list.h"

/* verifier si la liste est vide
 */
int thread_list_is_empty(thread_list list) {
  return list == NULL;
}

/* connaitre la taille de la liste
 */
int thread_list_size(thread_list list) {
  if (thread_list_is_empty(list))
    return 0;
  thread_list tmp = list;
  int size = 1;
  while(tmp->next != list) {
    size ++;
    tmp = tmp->next;
  }
  return size;
}

/* obtenir le premier element
 */ 
thread_t thread_list_first_elem(thread_list list) {
  return list->data;
}

/* obtenir le dernier element
 */
thread_t thread_list_last_elem(thread_list list) {
  thread_list tmp = list;
  while (tmp->next != list)
    tmp = tmp->next;
  return tmp->data;
}

thread_list thread_list_last(thread_list list) {
  thread_list tmp = list;
  while (tmp->next != list) 
    tmp = tmp->next;
  return tmp;
}

/* ajouter un element au debut de la liste
 */
thread_list thread_list_add_front(thread_list list, thread_t thread) {
  thread_list tmp = (thread_list) malloc(sizeof(struct thread_list_info));
  tmp->data = thread;
  tmp->next = tmp;
  tmp->previous = tmp;
  if (thread_list_is_empty(list))
    return tmp;
  tmp->previous = list->previous;
  list->previous->next = tmp;
  list->previous = tmp;
  tmp->next = list;
  return tmp;
}

/* prendre la liste definie par le deuxieme element
 */
thread_list thread_list_shift(thread_list list) {
  if (!thread_list_is_empty(list))
    list = list->next;
  return list;
}

/* ajouter un element a la fin de la liste
 */
thread_list thread_list_add_back(thread_list list, thread_t thread) {
  thread_list tmp = (thread_list) malloc(sizeof(struct thread_list_info));
  tmp->data = thread;
  tmp->next = tmp;
  tmp->previous  = tmp;
  if (thread_list_is_empty(list))
    return tmp;

  thread_list tmp2 = thread_list_last(list);
  tmp->previous = tmp2;
  tmp2->next = tmp;
  tmp->next = list;
  list->previous = tmp;
  return list;
}


/* supprimer un element de la liste
 */
thread_list thread_list_delete_elem(thread_list list, thread_t thread) {
  thread_list tmp = list;
  if (!thread_list_is_empty(tmp)) {
    if (thread_list_size(list) == 1)
      return NULL;
    if (thread == tmp->data) {
      list->next->previous = list->previous;
      list->previous->next = list->next;
      list = list->next;
      free(tmp);
    }
    else {
      while (tmp->next != list) 
	tmp = tmp->next;
      
      if (tmp->data == thread) {
	tmp->previous->next = tmp->next;
	tmp->next->previous = tmp->previous;
	free(tmp);
      }
    }
  }
  return list;
}


/* suppression de la liste
 */
thread_list thread_list_suppr(thread_list list) {
  thread_list tmp = list;
  if (!thread_list_is_empty(list)) {
    do {
      if (tmp->data != NULL) {
	thread_list_delete_elem(list,tmp->data);
	tmp->data = NULL;
      }
      thread_list tmp2 = tmp;
      tmp = tmp->next;
      if (NULL != tmp2) {
	free(tmp2);
	tmp2 = NULL;
      }
    } while (list != tmp);
  }
  return NULL;
}
    

